留言板、新增功能篇--(編輯、刪除)


Posted by s103071049 on 2021-06-22

1.編輯暱稱 2.編輯留言 3.刪除留言 4.分頁功能

編輯暱稱功能

各式作法:

  1. 放一個編輯暱稱鈕,點擊後連到新的頁面,輸入暱稱按提交就可以更新暱稱
  2. 直接在頁面放表單

先放入相對應的 input

<h3 class='greeting__word'>你好,<?php echo $nickname?>(^ω^)</h3>
    <form action="update_user.php" method="POST">
        新的暱稱:<input type="text" name="nickname">
        <input type="submit">
    </form>

調整樣式

<form action="update_user.php" method="POST" class="message">
    <div>新的暱稱 : <input type="text" name="nickname" class='register_input'></div>
    <input type="submit" class="submit__btn">
</form>

處理 update_user.php,將它命名的更好一點,變成 handle_update_user.php。

如果沒有 nickname 的話,進行錯誤處理顯示資料不齊全。
有 nickname 去資料庫改 nicknames。

<?php
  require_once('conn.php');
  session_start();
  $nickname = $_POST['nickname'];
  if (empty($nickname)) {
    header('Location: main.php?errCode=1');
    die('資料未輸入完整');
  }
  $username = $_SESSION['username'];
  $sql = 'update users set nickname=? where username=?';
  $stmt = $conn->prepare($sql);
  $stmt->bind_param("ss", $nickname, $username);
  $result = $stmt->execute();
  if (!$result) {
    die($conn->error);
  }
  header('Location: main.php');
?>

調整放置位置

<?php if (empty($username)) {?>
    <a href="login.php"><span>登入</span></a>
    <a href="register.php"><span>註冊</span></a>
    <?php  } else {?>
    <a href="logout.php"><span>登出</span></a>
    <a href="#" class="board__nickname"><span>編輯暱稱</span></a>
<?php } ?>
</div>
    <div class='desc'>
      <h2 class='title'>Comments</h2>
      <h3 class='greeting__word'>你好,<?php echo $nickname?>(^ω^)</h3>
    <form action="handle_update_user.php" method="POST" class="message hide board__nickname-form">
                <div>新的暱稱 : <input type="text" name="nickname" class='register_input'></div>
                <input type="submit" class="submit__btn">
                <hr>
    </form>

加上 js,點擊按鈕展開、不展開的設計

let btn = document.querySelector('.board__nickname')
btn.addEventListener('click', (e) => {
  let form = document.querySelector('.board__nickname-form')
  let textareaForm = document.querySelector('.board__add__comment-form')
  form.classList.toggle('hide')
  if (!form.classList.contains('hide')) {
    textareaForm.classList.add('hide')
  } else {
    textareaForm.classList.remove('hide')
  }
})

因為 comments 資料寫死了,所以編輯暱稱結束後,下面已經留過的言的暱稱不會一併更新。

資料庫正規化簡介

comments表中將 nickname 放入,如果我的 users 表改了 nickname 就無法同步更新。應該放 user_id 或 username 跟 users 表做關聯。

將資料庫重新整理過,去除依賴關係產生關連,就叫資料庫正規化。

調整 handle_add_comment.php

<?php
  require_once('conn.php');
  session_start();
  require_once('utils.php');
  $username = $_SESSION['username'];
  $content = $_POST['message__box'];

  if (empty($content)) {
    header('Location: main.php?errCode=1');
    die('未輸入內容');
  }

  $sql ='insert into comments(username, content) values(?, ?)';
  $stmt = $conn->prepare($sql);
  $stmt->bind_param('ss', $username, $content);
  $result = $stmt->execute();
  if(!$result) {
    header('Location: main.php?errCode=2');
    die ('Error' . $conn ->error);
  }
  header('Location: main.php');
?>s

資料庫 schema 參考

SQL join 語法介紹

要如何讓 users 和 comments 表利用 username 進行關聯。兩個表單之間的關聯會使用 SQL join

一般來說,最常用 left join。select * from comments left join users on comments.username = users.username
可以再細調 order by comments.id desc

會保留 comments 的內容,去找 users 的資料。
visual join

因為這樣改 main.php 資料會被覆蓋,所以需要幫資料表另取別名

  $stmt = $conn->prepare(
    'select * from comments ' . 
    'left join users on comments.username = users.username ' . 
    'order by comments.id desc');
  $stmt = $conn->prepare(
    'select ' .
      'C.id as id, C.content as content, C.create_at as create_at, ' .
      'U.nickname as nickname, U.username as username ' .
    'from comments as C ' . 
    'left join users as U on C.username = U.username ' . 
    'order by C.id desc');
# 這樣寫是因為用 * 會有欄位被覆蓋的問題

處理暱稱相同,辨識問題

<span class='nickname'>
    <?php echo escape($row['nickname'])?>
    (@<?php echo escape($row['username'])?>)
</span>

編輯留言功能

一、先加編輯留言的按鈕 <a href="update_comment.php?id=<?php echo $row['id']?>" >編輯</a>
二、限定只能編輯自己留言

<?php if ($username === $row['username']) {?>
  <a href="update_comment.php?id=<?php echo $row['id']?>" >編輯</a>
<?php }?>

三、製作 update_comment.php

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>HW8 留言板</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <div class='warning'>
        注意!本站為練習用網站,因教學用途刻意忽略資安的實作, 註冊時請勿使用任何真實的帳號或密碼。
    </div>
    <div class='content'>
        <div class='desc'>
            <h2 class='title'>編輯留言</h2>
            <h3 class='greeting__word'>你好,<?php echo $nickname?>(^ω^)</h3>
            <?php
                if (!empty($_GET['errCode'])) {
                  $errCode = $_GET['errCode'];
                  $msg = 'err';
                  if ($errCode === '1') {
                    $msg = '請輸入內容再提交 !';
                   }
                  echo '<h2 class="error__word-noContent"> 錯誤 : ' . $msg .'</h2>';
                }
            ?>
        </div>
        <form method="POST" action="handle_update_comment.php" class='message board__update__comment-form'>
            <textarea name="message__box" id="message__box" rows="10"></textarea>
            <input type="submit" name="submit" class="submit__btn">
          <hr>
        </form>
    </div>
</body>
</html>

四、編輯留言欄位,要出現原本的留言
透過 get 傳進來的 id,找到 comments,把它的內容抓出來,echo 到 textarea 的位置

<?php
  require_once('conn.php');
  require_once('utils.php');
  session_start();
  $id = $_GET['id'];
  $stmt = $conn->prepare(
    'select * from comments where id = ?'
  );
  $stmt->bind_param('i', $id);
  $result = $stmt->execute();
  if (!$result) {
    die('錯誤訊息 : ' . $conn ->error);
  }
  $result = $stmt->get_result();
  $row = $result->fetch_assoc();
?>
<textarea name="message__box" id="message__box" rows="10"><?php echo $row['content']?></textarea>

五、製作隱藏鈕,帶 id 值到 handle_update_comment.php
按下表單,handle_update_comment.php 需要知道按的是哪個 id

<input type="hidden" name="id" value="<?php echo $row['id']?>"/>

六、製作 handle_update_comment.php
直接 copy handle_update_users.php 進行修改

先調整 update_comment.php => name="content"

<textarea name="content" id="message__box" rows="10"><?php echo $row['content']?></textarea>

檢視有無 content,若無進行錯誤處理
handle_update_comment.php

<?php
  require_once('conn.php');
  session_start();
  $content = $_POST['content'];
  if (empty($content)) {
    header('Location: update_comment.php?errCode=1&id='.$_POST['id']);
    die('資料未輸入完整');
  }
  $username = $_SESSION['username'];
  $id = $_POST['id'];
  $sql = 'update comments set content=? where id=?';
  $stmt = $conn->prepare($sql);
  $stmt->bind_param("si", $content, $id);
  $result = $stmt->execute();
  if (!$result) {
    die($conn->error);
  }
  header('Location: main.php');
?>

刪除留言功能

一、製作刪除鈕

<a href="update_comment.php?id=<?php echo $row['id']?>" class="revise_btn">&emsp;編輯</a>
<a href="delete_comment.php?id=<?php echo $row['id']?>" class="revise_btn">&ensp;刪除</a>

二、製作 delete_comment.php

hard delete

真的從資料庫中刪除。

<?php
  require_once('conn.php');
  $id = $_GET['id'];
  if (empty($id)) {
    header('Location: main.php?errCode=1');
    die('資料未輸入齊全');
  }
  $sql ='delete from comments where id=?';
  $stmt = $conn->prepare($sql);
  $stmt->bind_param("i",$id);
  $result = $stmt->execute();
  if (!$result) {
    die($conn->error);
  }
  header('Location: main.php');
?>

soft delete

不會真的從資料庫中刪掉,只是畫面看起來像是刪掉。

從資料庫 comments 表新增一個欄位:isdeleted 如果是 1 表示刪掉,是 0 表示沒刪。目的是怕誤刪資料,有一天無法復原。

調整代碼,在 update 將 is_deleted 設成 1

$sql ='update comments set is_deleted=1 where id=?';

改 main.php
寫 query 時先用 left join 再用 where 將資料篩選出來。

  $stmt = $conn->prepare(
    'select ' .
      'C.id as id, C.content as content, C.create_at as create_at, ' .
      'U.nickname as nickname, U.username as username ' .
    'from comments as C ' . 
    'left join users as U on C.username = U.username ' .
    'where C.is_deleted is Null ' .
    'order by C.id desc');

#form #SQL #PHP







Related Posts

.Net MVC authorization Controller and Workcontext extension in razor view

.Net MVC authorization Controller and Workcontext extension in razor view

使用OpenSSL建立自簽SSL憑證

使用OpenSSL建立自簽SSL憑證

2. 架構完整的 React 專案結構

2. 架構完整的 React 專案結構


Comments